package com.peko.ocv.Controller;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.HashSet;
import java.util.Set;

public class MyController {

    static {
        //必须要写
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("opencv\t"+Core.VERSION);
    }

    /**
     * 计算滑块对应背景位置的x坐标
     * @param args
     */
    public static void main(String[] args) {

        //加载滑块
        String blockPicPath = "D:/my_project/yanzhengtu/huakuai/f.jpg";
        Mat blockMat = Imgcodecs.imread(blockPicPath);
        //清除图片的空白区域
        blockMat = clearWhite(blockMat);
        //图片 COLOR_RGB2GRAY 灰度化
        Imgproc.cvtColor(blockMat, blockMat, Imgproc.COLOR_RGB2GRAY);
        //图像边缘检测
        blockMat = imageEdgeDetection(blockMat);

        //加载背景图
        String backGroundPicPath = "D:/my_project/yanzhengtu/beijingtu/f.jpg";
        Mat backGroundMat = Imgcodecs.imread(backGroundPicPath);
        //图像边缘检测
        backGroundMat = imageEdgeDetection(backGroundMat);
        //这部分又将图像RBG化了，不是很能理解，至少在视觉上没看出来处理前有什么区别
        Imgproc.cvtColor(blockMat, blockMat, Imgproc.COLOR_GRAY2RGB);
        Imgproc.cvtColor(backGroundMat, backGroundMat, Imgproc.COLOR_GRAY2RGB);

        Mat g_result = new Mat();
        //图像匹配（TM_CCOEFF_NORMED算法）
        Imgproc.matchTemplate(backGroundMat, blockMat, g_result, Imgproc.TM_CCOEFF_NORMED);
        Point matchLocation = Core.minMaxLoc(g_result).maxLoc;
        //获取匹配的 x 位置
        System.out.println(matchLocation.x);
    }

    /**
     * 清除图片的空白区域
     * @param mat
     * @return
     */
    public static Mat clearWhite(Mat mat){

        int row = mat.rows();
        int col = mat.cols();
        int min_x = 255,min_y = 255,max_x = 0,max_y = 0;

        Set<double[]> set = new HashSet<>();
        for(int x = 1;x <= row;x++){
            for(int y = 1;y <= col;y++){
                set.add(mat.get(x,y));
                if(set.size() >= 2){
                    if(x <= min_x){
                        min_x = x;
                    }else if( x >= max_x){
                        max_x = x;
                    }

                    if(y <= min_y){
                        min_y = y;
                    }else if( y >= max_y){
                        max_y = y;
                    }
                }
            }
        }
        return mat.submat(min_x,max_x,min_y,max_y);
    }

    /**
     * 图像边缘检测
     * @param mat
     * @return
     */
    public static Mat imageEdgeDetection(Mat mat){
        Mat target = new Mat();
        Imgproc.Canny(mat,target,100,200);
        return target;
    }


//    /**
//     * 另一个不太准确的算法（弃用）
//     * @param args
//     */
//    public static void main(String[] args) {
//        String slideBgPicPath = "D:/my_project/yanzhengtu/beijingtu/e.jpg";
//        String slideBlockPicPath = "D:/my_project/yanzhengtu/huakuai/e.jpg";
//        System.out.println("匹配的位置："+pictureMatch(slideBgPicPath,slideBlockPicPath));
//    }

//    public static double pictureMatch(String slideBgPicPath,String slideBlockPicPath){
//
//        //对滑块进行处理
//        Mat slideBlockMat = Imgcodecs.imread(slideBlockPicPath);
//        System.out.println("滑块的x："+slideBlockMat.cols()+ "     滑块的y："+slideBlockMat.rows());
//
//        //1、灰度化图片
//        Imgproc.cvtColor(slideBlockMat, slideBlockMat, Imgproc.COLOR_BGR2GRAY);
//        //2、去除周围黑边
//        for (int row = 0; row < slideBlockMat.height(); row++) {
//            for (int col = 0; col < slideBlockMat.width(); col++) {
//                if (slideBlockMat.get(row, col)[0] == 0) {
//                    slideBlockMat.put(row, col, 96);
//                }
//            }
//        }
//        //3、inRange二值化转黑白图
//        Core.inRange(slideBlockMat, Scalar.all(96), Scalar.all(96), slideBlockMat);
//
//        HighGui gui1 =new HighGui();
//        gui1.imshow("处理后的图片",slideBlockMat);
//        gui1.waitKey(5);
//
//        //对滑动背景图进行处理
//        Mat slideBgMat = Imgcodecs.imread(slideBgPicPath);
//        System.out.println("背景图的x："+slideBgMat.cols()+ "  背景图的y："+slideBgMat.rows());
//        //1、灰度化图片
//        Imgproc.cvtColor(slideBgMat, slideBgMat, Imgproc.COLOR_BGR2GRAY);
//        //2、二值化
//        Imgproc.threshold(slideBgMat, slideBgMat, 127, 255, Imgproc.THRESH_BINARY); Mat g_result = new Mat();
//        /**
//         * matchTemplate：在模板和输入图像之间寻找匹配,获得匹配结果图像
//         * result：保存匹配的结果矩阵
//         * TM_CCOEFF_NORMED：标准相关匹配算法
//         */
//        Imgproc.matchTemplate(slideBgMat, slideBlockMat, g_result, Imgproc.TM_CCOEFF_NORMED);
//        /**
//         * minMaxLoc：在给定的结果矩阵中寻找最大和最小值，并给出它们的位置
//         * maxLoc：最大值
//         */
//        Point matchLocation = Core.minMaxLoc(g_result).maxLoc;
//
////        HighGui gui2 =new HighGui();
////        gui2.imshow("处理后的图片",slideBgMat);
////        gui2.waitKey(5);
//
//        //返回匹配点的横向距离
//        return matchLocation.x;
//    }
}
